package cdai

import (
	"crypto/sha256"
	"crypto/tls"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"gin/cdai/response"
	"gin/common"
	"github.com/spf13/viper"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
	"io/ioutil"
	"net/http"
	"net/http/cookiejar"
	"sort"
	"time"
)

var (
	accessSecret string
	accessKey    string
	apiDomain    string
	httpClient   *http.Client
	apiTimeout   int
)

func Init() {
	accessKey = viper.GetString("cdai.access_key")
	accessSecret = viper.GetString("cdai.access_secret")
	apiDomain = viper.GetString("cdai.domain")
	apiTimeout = viper.GetInt("cdai.timeout")
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	//http cookie接口
	cookieJar, _ := cookiejar.New(nil)
	httpClient = &http.Client{
		Timeout:   time.Duration(apiTimeout) * time.Second,
		Jar:       cookieJar,
		Transport: tr,
	}
}

func GetApiDomain() string {
	return apiDomain
}

func GetHttpClient() *http.Client {
	return httpClient
}

// 获得请求参数字典 签名
func GetSign(requestBody *map[string]interface{}) string {
	res := accessSecret
	requestBodyKeys := make([]string, len(*requestBody))

	index := 0
	for key, _ := range *requestBody {
		requestBodyKeys[index] = key
		index++
	}
	sort.Strings(requestBodyKeys)
	for _, key := range requestBodyKeys {
		res += key + common.StrVal((*requestBody)[key])
	}
	d := sha256.New()
	d.Write([]byte(res))
	bytes := d.Sum(nil)
	res = hex.EncodeToString(bytes)
	return res
}

func BuildCredentialHeader(r *http.Request, params *map[string]interface{}) *http.Request {
	r.Header.Set("Ak", accessKey)
	r.Header.Set("Sign", GetSign(params))
	return r
}

func ParseFromHttpResponse(hr *http.Response, response response.Response) (err error) {
	defer hr.Body.Close()
	body, err := ioutil.ReadAll(hr.Body)
	if err != nil {
		msg := fmt.Sprintf("Fail to read response body because %s", err)
		return errors.NewTencentCloudSDKError("ClientError.IOError", msg, "")
	}
	if hr.StatusCode != 200 {
		msg := fmt.Sprintf("Request fail with http status code: %s, with body: %s", hr.Status, body)
		return errors.NewTencentCloudSDKError("ClientError.HttpStatusCodeError", msg, "")
	}
	//log.Printf("[DEBUG] Response Body=%s", body)
	err = response.ParseErrorFromHTTPResponse(body)
	if err != nil {
		return
	}
	err = json.Unmarshal(body, &response)
	if err != nil {
		msg := fmt.Sprintf("Fail to parse json content: %s, because: %s", body, err)
		return errors.NewTencentCloudSDKError("ClientError.ParseJsonError", msg, "")
	}
	return
}
